# -*- coding:utf-8 -*-

## =====================================================================
## Copyright (C) 2007-2011  Jean-Philippe GOLAY
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## =====================================================================


from Tkinter import *
import Pmw
from tkMessageBox import *

from Persistance import *
from iCalendar import CalendarGUI
from iNotes import NotesGUI
from iStaff import StaffListGUI
from iStock import StockListGUI


class InvantoryGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set()
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Inventaire")
		self.balloon=balloon
		self.imgSave=PhotoImage(file="img/save_icon.gif")
		self.imgDelete=PhotoImage(file="img/delete_icon.gif")
		self.imgCalendar=PhotoImage(file="img/calendar.gif")
		self.imgSearch=PhotoImage(file="img/search_icon.gif")
		self.imgNotes=PhotoImage(file="img/edit.gif")
		self.hoursListCB = Glob.HOURS_LIST
		self.minutesListCB = Glob.MINUTES_LIST
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Iventory-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Inventory-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas l'icône que je veux lui mettre...")
		self.log.info("\tInvantoryGUI\tStart")
		self.makeInvantory()

	# DEBUT de la gestion du module Invantory --------------------------------------------------------------------------------------------------------
	def clearFieldInvantory(self):
		# Mise a zéro des champs
		self.invantoryValues[0].set("")
		self.invantoryValues[1].set("")
		self.invantoryValues[2].set("")
		self.invantoryValues[3].set("")
		self.invantoryValues[4].set("")
		self.invantoryValues[5].set("")
		self.listObject=[Stock,Staff]

	def selectInvantory(self, event):
		if self.listInvantory.get(0)!="":
			result = Invantory.select(Invantory.q.id==self.idListInvantory[int(self.listInvantory.curselection()[0])])
			for row in result:
				self.selectedInvantory = row
			self.listObject[0]=self.selectedInvantory.stock
			self.listObject[1]=self.selectedInvantory.checkBy
			self.invantoryValues[0].set(self.listObject[0].item.designation)
			self.invantoryValues[4].set(self.listObject[1].fname+" - "+self.listObject[1].lname)
			if self.selectedInvantory.checkQuantity != None:self.invantoryValues[2].set(self.selectedInvantory.checkQuantity)
			if self.selectedInvantory.differenceQuantity != None:self.invantoryValues[3].set(self.selectedInvantory.differenceQuantity)
			if self.selectedInvantory.notes != None:self.invantoryValues[5].set(self.selectedInvantory.notes)
			if self.selectedInvantory.date != None:self.invantoryValues[1].set(self.selectedInvantory.date.strftime("%d/%m/%Y"))
			# activation du bouton supprimer
			self.deleteInvantoryBt.config(state=NORMAL)

	def searchInvantory(self, event=None):
		if self.searchInvantoryValue.get() != "":
			self.listInvantory.delete(0,END)
			self.idListInvantory = []
			result = Invantory.select(Invantory.q.notes.startswith(self.searchInvantoryValue.get().encode("utf-8")), orderBy=Invantory.q.date)
			for row in result:
				self.listInvantory.insert(END, row.stock.item.designation+" - "+row.date.strftime("%d/%m/%Y")+" - "+str(row.checkQuantity)+" - "+str(row.differenceQuantity))
				self.idListInvantory.append(row.id)
		else:
			self.listInvantory.delete(0,END)
			self.idListInvantory = []
			result = Invantory.select(orderBy=Invantory.q.date)
			for row in result:
				self.listInvantory.insert(END, row.stock.item.designation+" - "+row.date.strftime("%d/%m/%Y")+" - "+str(row.checkQuantity)+" - "+str(row.differenceQuantity))
				self.idListInvantory.append(row.id)

	def makeInvantory(self):
		leftFrame = Frame(self)
		# Fiche Invantory  (présentation colonne de gauche)
		Label(leftFrame, text=u"Inventaire").pack(side=TOP, fill=X)
		# Création des champs a renseigner pour un object Invantory
		invantoryLabels = (u"Réf Stock", u"Date", u"Quantité comptée",u"Différence", u"Vérifié par", u"Notes")
		self.invantoryValues = [StringVar(), StringVar(), StringVar(), StringVar(), StringVar(), StringVar()]
		count = 0
		for name in invantoryLabels:
			f = Frame(leftFrame)
			Label(f, width=18, text=name, anchor=W).pack(side=LEFT)
			if count == 0: # Stock
				Entry(f, textvariable=self.invantoryValues[count], width=21, state=DISABLED, bd=0, disabledforeground="black").pack(side=LEFT, fill=X)
				myStock=Button(f, image=self.imgSearch, command=lambda x=self.invantoryValues[count]:self.ctrlListStock(x), padx=4, pady=1)
				myStock.pack(side=RIGHT)
				self.balloon.bind(myStock, u"Séléctionner un Article en Stock")
			elif count == 1: # Date
				Entry(f, textvariable=self.invantoryValues[count], width=21).pack(side=LEFT, fill=X)
				myCal1=Button(f, image=self.imgCalendar, command=lambda x=self.invantoryValues[count]:self.ctrlCalendar(x), padx=4, pady=1)
				myCal1.pack(side=LEFT)
				self.balloon.bind(myCal1, u"Calendrier")
			elif count == 4: # Staff
				Entry(f, textvariable=self.invantoryValues[count], width=21, state=DISABLED, bd=0, disabledforeground="black").pack(side=LEFT, fill=X)
				myStaff=Button(f, image=self.imgSearch, command=lambda x=self.invantoryValues[count]:self.ctrlListStaff(x), padx=4, pady=1)
				myStaff.pack(side=RIGHT)
				self.balloon.bind(myStaff, u"Séléctionner un Employé")
			elif count == 5: # Notes
				Entry(f, textvariable=self.invantoryValues[count], width=21).pack(side=LEFT, fill=X)
				myNotes=Button(f, image=self.imgNotes, command=lambda x=self.invantoryValues[count]:self.ctrlNotes(x,u"Notes inventaire"), padx=4, pady=1)
				myNotes.pack(side=RIGHT)
				self.balloon.bind(myNotes, u"Détails de la note")
			else: 
				Entry(f, textvariable=self.invantoryValues[count], width=24).pack(side=LEFT, fill=X)
			f.pack(side=TOP, fill=X)
			count += 1
		# Boutons enregistrement (new ou modify) et suppression
		s = Frame(leftFrame) 
		self.saveInvantoryBt=Button(s, image=self.imgSave, command=self.createInvantory)
		self.saveInvantoryBt.bind("<Return>", self.createInvantory)
		self.saveInvantoryBt.pack(side=LEFT)
		self.balloon.bind(self.saveInvantoryBt, u"Enregistrer")
		self.deleteInvantoryBt=Button(s, image=self.imgDelete, command=self.deleteInvantory, state=DISABLED)
		self.deleteInvantoryBt.bind("<Return>", self.deleteInvantory)
		self.deleteInvantoryBt.pack(side=LEFT)
		self.balloon.bind(self.deleteInvantoryBt, u"Supprimer")
		s.pack(side=TOP, fill=X)
		leftFrame.pack(side=LEFT, fill=X)
		# Liste des Invantory existants (présentation colonne de droite)
		rightFrame = Frame(self) 
		Label(rightFrame, text=u"Lignes d'inventaire").pack(side=TOP, fill=X)
		self.searchInvantoryValue = StringVar()
		self.searchInvantoryEt = Entry(rightFrame,  width=63, textvariable=self.searchInvantoryValue, relief=GROOVE)
		self.searchInvantoryEt.bind("<KeyRelease>", self.searchInvantory)
		self.searchInvantoryEt.pack(side=TOP, fill=X)
		self.balloon.bind(self.searchInvantoryEt, u"Saisir les premières lettres d'une ligne d'inventaire\npour une recherche plus précise,\nla liste est classée par date.")
		s = Frame(rightFrame) 
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listInvantory = Listbox(s)
		self.listInvantory.config(yscrollcommand=scrollbar.set, width=60, selectmode=SINGLE, height=8)
		self.listInvantory.bind("<ButtonRelease-1>",self.selectInvantory)
		scrollbar.config(command=self.listInvantory.yview)
		self.listInvantory.pack()
		self.balloon.bind(self.listInvantory, u"Séléctionner une ligne d'inventaire\npour la visualiser ou la modifier.")
		s.pack(side=TOP, fill=X)
		rightFrame.pack(side=RIGHT, fill=BOTH)
		# Initialisation
		self.clearFieldInvantory()
		self.searchInvantory()

	def ctrlCalendar(self,field):
		CalendarGUI(field=field, log=self.log, path=self.path)

	def ctrlNotes(self,field,title):
		NotesGUI(field=field,title=title, log=self.log, path=self.path)

	def ctrlListStock(self,field): # index 0
		StockListGUI(balloon=self.balloon, field=field, index=0, listObject=self.listObject, log=self.log, path=self.path)

	def ctrlListStaff(self,field): # index 1
		StaffListGUI(balloon=self.balloon, field=field, index=1, listObject=self.listObject, log=self.log, path=self.path)

	def getDateTimeDeliveryDateInvantory(self):
		if self.invantoryValues[1].get() != "":
			date=self.invantoryValues[1].get().split("/")
			d = datetime.date(int(date[2]), int(date[1]), int(date[0]))
			return d
		else:
			return None

	def verifyInvantory(self):
		if self.invantoryValues[0].get() == "":
			showerror(u"Erreur de saisie", u"Le champ Réf de stock est obligatoire !\nMerci de le compléter.")
			return False
		elif self.invantoryValues[1].get() == "": 
			showerror(u"Erreur de saisie", u"Le champ Date de livraison est obligatoire !\nMerci de le compléter.")
			return False
		elif self.invantoryValues[2].get() == "": 
			showerror(u"Erreur de saisie", u"Le champ Quantité comptée est obligatoire !\nMerci de le compléter.")
			return False      
		elif self.invantoryValues[3].get() == "": 
			showerror(u"Erreur de saisie", u"Le champ Différence est obligatoire !\nMerci de le compléter.")
			return False              
		elif self.invantoryValues[4].get() == "": 
			showerror(u"Erreur de saisie", u"Le champ Vérifié par est obligatoire !\nMerci de le compléter.")
			return False
		else:
			return True

	def createInvantory(self, event=None):
		if self.verifyInvantory():
			if  self.deleteInvantoryBt.config()["state"][4] == "normal":
				self.modifyInvantory()
			else:
				if askyesno(u"Enregistrement", u"Souhaitez-vous enregistrer %s comme une nouvelle ligne d'inventaire ?\n" % self.invantoryValues[1].get()):
					Invantory(stock=self.listObject[0],
						date=self.getDateTimeDeliveryDateInvantory(),
						checkQuantity=self.invantoryValues[2].get().encode("utf-8"),
						differenceQuantity=self.invantoryValues[3].get().encode("utf-8"),
						checkBy=self.listObject[1],
						notes=self.invantoryValues[5].get().encode("utf-8"),
						createDate=datetime.datetime.now()
					)
					self.searchInvantory()
				self.clearFieldInvantory()

	def modifyInvantory(self, event=None): 
		if askyesno(u"Modifier", u"Souhaitez-vous modifier la ligne d'inventaire %s ?" % self.selectedInvantory.id):
			self.selectedInvantory.stock=self.listObject[0]
			self.selectedInvantory.date=self.getDateTimeDeliveryDateInvantory()
			self.selectedInvantory.checkQuantity=self.invantoryValues[2].get().encode("utf-8")
			self.selectedInvantory.deliveryQuantity=self.invantoryValues[3].get().encode("utf-8")
			self.selectedInvantory.checkBy=self.listObject[1]
			self.selectedInvantory.notes=self.invantoryValues[5].get().encode("utf-8")
			self.searchInvantory()
		self.deleteInvantoryBt.config(state=DISABLED)
		self.clearFieldInvantory()

	def deleteInvantory(self, event=None): 
		if askyesno(u"Suppression", u"Souhaitez-vous supprimer la inventory %s ?\nCette opération est irréversible !" % self.selectedInvantory.id):
			Invantory.delete(self.selectedInvantory.id)
			self.searchInvantory()            
		self.deleteInvantoryBt.config(state=DISABLED)
		self.clearFieldInvantory()
	# FIN de la gestion du module Invantory ---------------------------------------------------------------------------------------------------------

class InvantoryListGUI(Toplevel):
	def __init__(self, parent=None, balloon=None, field=None, index=None, listObject=None, path=None, log=None):
		Toplevel.__init__(self, parent)
		self.parent=parent
		self.grab_set() 
		self.transient(self.master)
		self.resizable(width=False, height=False)
		self.title(u"Liste des Inventaire")
		self.balloon=balloon
		self.field=field
		self.index=index
		self.listObject=listObject
		self.path=path
		self.log=log
		# Afficher un icon personnalisé
		try:
			if os.name =="posix":
				img = PhotoImage(file=self.path+"/icons/Inventory-icon.gif")
				self.tk.call("wm", "iconphoto", self._w, img)
			else:
				self.iconbitmap(default=self.path+"/icons/Inventory-icon.gif")
		except TclError:
			self.log.warning("Le window manager ne supporte pas l'icône que je veux lui mettre...")
		self.log.info("\tInvantoryListGUI\tStart")
		self.makeListInvantory()

	def selectListInvantory(self, event):
		if self.listListInvantory.get(0)!="":
			result = Invantory.select(Invantory.q.id==self.idListListInvantory[int(self.listListInvantory.curselection()[0])])
			for row in result:
				self.listObject[self.index]=row
				self.field.set(row.item.designation)
				self.destroy()

	def searchListInvantory(self, event=None):
		if self.searchListInvantoryValue.get() != "":
			self.listListInvantory.delete(0,END)
			self.idListListInvantory = []
			result = Invantory.select(Invantory.q.notes.startswith(self.searchListInvantoryValue.get().encode("utf-8")), orderBy=Invantory.q.date)
			for row in result:
				self.listListInvantory.insert(END, row.stock.item.designation+" - "+row.date.strftime("%d/%m/%Y")+" - "+str(row.checkQuantity)+" - "+str(row.differenceQuantity))
				self.idListListInvantory.append(row.id)
		else:
			self.listListInvantory.delete(0,END)
			self.idListListInvantory = []
			result = Invantory.select(orderBy=Invantory.q.date)
			for row in result:
				self.listListInvantory.insert(END, row.stock.item.designation+" - "+row.date.strftime("%d/%m/%Y")+" - "+str(row.checkQuantity)+" - "+str(row.differenceQuantity))
				self.idListListInvantory.append(row.id)

	def makeListInvantory(self):
		leftFrame = Frame(self)
		Label(leftFrame, text=u"Liste des lignes d'inventaires").pack(side=TOP, fill=X)
		self.searchListInvantoryValue = StringVar()
		s = Frame(leftFrame) 
		self.searchListInvantoryEt = Entry(s,  width=25, textvariable=self.searchListInvantoryValue, relief=GROOVE)
		self.searchListInvantoryEt.bind("<KeyRelease>", self.searchListInvantory)
		self.searchListInvantoryEt.pack(side=LEFT, fill=X)
		self.balloon.bind(self.searchListInvantoryEt, u"Saisir les premiéres lettres d'une ligne d'inventaire\npour une recherche plus précise,\nla liste est classée par date.")
		Button(s, text=u"New", command=self.ctrlInvantory, relief=FLAT).pack(side=RIGHT)
		s.pack(side=TOP, fill=X)
		s = Frame(leftFrame) 
		scrollbar = Scrollbar(s)
		scrollbar.pack(side=RIGHT, fill=Y)
		self.listListInvantory = Listbox(s)
		self.listListInvantory.config(yscrollcommand=scrollbar.set,width=30, selectmode=SINGLE, height=16)
		self.listListInvantory.bind("<ButtonRelease-1>",self.selectListInvantory)
		scrollbar.config(command=self.listListInvantory.yview)
		self.listListInvantory.pack()
		self.balloon.bind(self.listListInvantory, u"Séléctionner un Séjour.")
		s.pack(side=TOP, fill=X)
		leftFrame.pack()
		self.searchListInvantory()

	def ctrlInvantory(self):
		InvantoryGUI(balloon=self.balloon, log=self.log, path=self.path)